package com.hllxd.hism.star.basic.service.service;


import com.alibaba.fastjson.JSON;
import com.hllxd.hism.star.basic.service.dao.mapper.doris.RockTableStoreMapper;
import com.hllxd.hism.star.basic.service.dao.mapper.doris.RockTaskInstMapper;
import com.hllxd.hism.star.basic.service.dao.mapper.mis.CostQuotaMapper;
import com.hllxd.hism.star.basic.service.model.cost.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;

/**
 * 消费报告
 *
 * @author lixiyong
 * @date 2020/12/20 16:15
 * buCode 业务团队
 * period 周期day，week， month
 */
@Slf4j
@Service("costReportService")
public class CostReportServiceImpl implements CostReportService {

    final static String ZERO = "0";
    private static final Long KB = 1024L;
    private static final Long MB = 1024L * 1024L;
    private static final Long GB = 1024L * 1024L * 1024L;
    private static final Long TB = 1024L * 1024L * 1024L * 1024L;
    private static final Long PB = 1024L * 1024L * 1024L * 1024L * 1024L;
//    @Autowired
//    private CostReportMapper costReportMapper;


    @Autowired
    private RockTaskInstMapper rockTaskInstMapper;

    @Autowired
    private RockTableStoreMapper rockTableStoreMapper;

    @Autowired
    private CostQuotaMapper costQuotaMapper;


//    @Override
//    public List<CostReportEntity> queryCostReport(String ownerID, String period, String ptdate) {
//        List<CostReportEntity> result = null;
//        if (ownerID == null || ownerID.isEmpty() || ownerID.equals(ZERO)) {
//            ownerID = null;
//        }
//        switch (period) {
//            case "day":
//                result = costReportMapper.listCostReport4Day(ownerID, ptdate);
//                break;
//            case "week":
//                result = costReportMapper.listCostReport4Week(ownerID, ptdate);
//                break;
//            case "month":
//                result = costReportMapper.listCostReport4Month(ownerID, ptdate);
//                break;
//            default:
//                break;
//        }
//        return result;
//    }

//    @Override
//    public List<CostReportEntity> listCostTaskReport4Team2(String buCode, String period, String ptdate) {
//        log.info("queryCostReportTeam: {}, {}, {}.", period, buCode, period);
//
//        if (buCode == null || buCode.isEmpty() || buCode.equals(ZERO)) {
//            buCode = null;
//        }
//        List<CostReportEntity> result = null;
//        switch (period) {
//            case "day":
//                result = costReportMapper.listCostReportTeam4Day(buCode, ptdate);
//                break;
//            case "week":
//                result = costReportMapper.listCostReportTeam4Week(buCode, ptdate);
//                break;
//            case "month":
//                result = costReportMapper.listCostReportTeam4Month(buCode, ptdate);
//                break;
//            default:
//                break;
//        }
//        return result;
//    }

    @Override
    public List<CostReportEntity> listCostTableReport4Team(String dt, String basePath) {
        log.info("listCostTableReport4Team: {}, {}.", dt, basePath);
        if(basePath==null || basePath.equals("0")) {
            basePath = null;
        }
        List<CostReportEntity> results = rockTableStoreMapper.listCostReport4Team(dt, basePath);
        for(CostReportEntity entity:results) {
            if(entity==null) {
                log.info("nil.");
            }
            log.info("{}", JSON.toJSONString(entity));
        }
        return results;
    }

    @Override
    public List<CostReportEntity> listCostTableReport4Owner(String dt, String ownerId, String basicPath) {
        log.info("listCostTableReport4Owner: {}, {}, {}.", dt, ownerId, basicPath);
        if(ownerId==null || ownerId.equals("0")) {
            ownerId = null;
        }
        return rockTableStoreMapper.listCostReport4Owner(dt,ownerId,basicPath);
    }


    @Override
    public List<CostReportDetailEntity> listCostTableReportDetail(String dt, String ownerId, String basicPath) {
        if(ownerId==null || ownerId.equals("0")) {
            ownerId = null;
        }
        return rockTableStoreMapper.listCostTableReportDetail(dt,ownerId,basicPath);
    }

    private String[] getYearInterval() {
        LocalDateTime time = LocalDateTime.now();
        LocalDateTime time2 = time.minusDays(366);
        String startTime = time2.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        String endTime = time.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        return new String[]{startTime, endTime};
    }

    @Override
    public List<CostTaskReportEntity> listCostTaskReport4Team(String dt, String queueName) {
        return rockTaskInstMapper.listCostTaskReport4Team(dt, queueName);

    }

    @Override
    public List<CostTaskReportEntity> listCostTaskReport4Owner(String dt, String queueName, String ownerId) {
        log.info("listCostTaskReport4Owner, dt: {}, queueName: {}, ownerId: {}.", dt, queueName, ownerId);
        if(queueName==null || queueName.equals("0")) {
            queueName = null;
        }
        if(ownerId==null || ownerId.equals("0")|| ownerId.equals("all")) {
            ownerId = null;
        }
        return rockTaskInstMapper.listCostTaskReport4Owner(dt, queueName, ownerId);

    }

    @Override
    public List<CostTaskEntity> listCostTaskReportDetail(String dt, String queueName, String ownerId) {
        if(queueName==null || queueName.equals("0")) {
            queueName = null;
        }
        if(ownerId==null || ownerId.equals("0")) {
            ownerId = null;
        }
        return rockTaskInstMapper.listCostTaskReport(dt, queueName, ownerId);

    }

    @Override
    public CostTaskDetailChartEntity loadCostTaskReportTrend(CostTaskEntity aa) {
        List<CostTaskEntity> list = rockTaskInstMapper.getCostTaskDetailChart(aa.getTaskId());
        if (list != null && list.size() > 0) {
            ArrayList<Object[]> data = new ArrayList<>();
            List<List<Long>> useTimesList = new ArrayList<>();
            String basicReportDate = list.get(0).getReportDate();
            ArrayList<Long> values = new ArrayList<>();
            for (CostTaskEntity costTaskEntity : list) {
                String reportDate = costTaskEntity.getReportDate();
                if (!basicReportDate.equals(reportDate)) {
                    useTimesList.add(values);
                    values = new ArrayList<>();
                    basicReportDate = reportDate;
                }
                Object[] objects = new Object[6];
                objects[0] = reportDate;
                objects[1] = Long.parseLong(costTaskEntity.getStartTime());
                objects[2] = Long.parseLong(costTaskEntity.getFinishTime());
                objects[3] = Long.parseLong(costTaskEntity.getBasicTime());
                objects[4] = Long.parseLong(costTaskEntity.getFinishTime());
                objects[5] = costTaskEntity.getUseTime();
                values.add(costTaskEntity.getUseTime());
                data.add(objects);
            }
            useTimesList.add(values);


            int size1 = useTimesList.size();
            int size2 = 0;
            for (List<Long> longs : useTimesList) {
                size2 = Math.max(size2, longs.size());
            }
            Long[][] useTimes = new Long[size2][size1];
            for (int i = 0; i < useTimes.length; i++) {
                for (int j = 0; j < useTimes[i].length; j++) {
                    useTimes[i][j] = 0L;
                    if (useTimesList.size() > j) {
                        List<Long> jList = useTimesList.get(j);
                        if (jList.size() > i) {
                            useTimes[i][j] = jList.get(i);
                        }
                    }

                }
            }
            CostTaskDetailChartEntity entity = new CostTaskDetailChartEntity();
            entity.setTaskId(list.get(0).getTaskId());
            entity.setTaskName(list.get(0).getTaskName());
            entity.setChartData(data);
            entity.setUseTimes(useTimes);
            return entity;
        }

        return null;
//        return null;
    }

    @Override
    public List<CostQuotaEntity> listCostQuota() {

        return costQuotaMapper.listCostQuota();
    }

    @Override
    public CostQuotaEntity loadCostQuota(Long id) {
        log.info("loadCostQuota， id: {}.", id);
        return costQuotaMapper.getCostQuota(id);
    }

    @Override
    public Long setCostQuota(CostQuotaEntity entity) {
        if(entity==null) {
            return -1L;
        }
        log.info("setCostQuota, json: {}.", JSON.toJSONString(entity));
        if(entity.id>0) {
            return costQuotaMapper.updateCostQuota(entity);
        }else {
            return costQuotaMapper.insertCostQuota(entity);
        }
    }


//    @Override
//    public List<CostReportEntity> listCostTableReport(String dt, String ownerId, String basicPath) {
//        if (ownerId == null || ownerId.isEmpty() || ownerId.equals(ZERO)) {
//            ownerId = null;
//        }
//        return rockTableStoreMapper.listCostTableReport(dt, ownerId, basicPath);
//    }

    @Override
    public CostUserChartEntity loadCostTableReportTrend(String ownerId, String basicPath) {

        String[] dtArr = getYearInterval();
        double maxStoreSizeD = 0;
        log.info("params: {}, {}, ownerId: {}.", dtArr[0],dtArr[1],ownerId);
        List<CostReportEntity> costReportEntities = rockTableStoreMapper.loadCostTableReportTrend(dtArr[0],dtArr[1],ownerId,basicPath);
        for (CostReportEntity costReportEntity : costReportEntities) {
            String storeSize = costReportEntity.getStoreSize();
            double storeSizeD = Double.parseDouble(storeSize);
            maxStoreSizeD = Math.max(maxStoreSizeD, storeSizeD);
        }
        String unitName = "GB";
        if (maxStoreSizeD < KB) {
            unitName = "B";
        } else if (maxStoreSizeD < MB) {
            unitName = "KB";
        } else if (maxStoreSizeD < GB) {
            unitName = "MB";
        } else if (maxStoreSizeD < TB) {
            unitName = "GB";
        } else if (maxStoreSizeD < PB) {
            unitName = "TB";
        } else {
            unitName = "PB";
        }
        ArrayList<String> xList = new ArrayList<>();
        ArrayList<Double> values = new ArrayList<>();
        int valueIndex = 0;
        if (costReportEntities.size() >= 1) {
            String startDateStr = costReportEntities.get(0).getDt();
            LocalDate startDate = LocalDate.parse(startDateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            LocalDateTime newDataTime = LocalDateTime.now().minusDays(1);
            long until = startDate.until(newDataTime, ChronoUnit.DAYS);
            for (int i = 0; i <= until; i++) {
                LocalDate localDate = startDate.plusDays(i);
                String dateStr = localDate.toString();
                String dbDateStr = localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                xList.add(dateStr);
                if (costReportEntities.size() > valueIndex) {
                    CostReportEntity entity = costReportEntities.get(valueIndex);
                    if (dbDateStr.equals(entity.getDt())) {
                        values.add(parseValueByUnit(entity.getStoreSize(), unitName));
                        valueIndex++;
                    } else {
                        values.add(null);
                    }
                } else {
                    values.add(null);
                }

            }
        }
        CostUserChartEntity entity = new CostUserChartEntity();
        entity.setXAxisData(xList);
        entity.setValues(values);
        entity.setDataUnitName(unitName);

        return entity;
    }

    private Double parseValueByUnit(String storeSize, String unitName) {
        double value;
        switch (unitName) {
            case "KB":
                value = new BigDecimal(storeSize).divide(new BigDecimal(KB), 2, RoundingMode.HALF_UP).doubleValue();
                break;
            case "MB":
                value = new BigDecimal(storeSize).divide(new BigDecimal(MB), 2, RoundingMode.HALF_UP).doubleValue();
                break;
            case "GB":
                value = new BigDecimal(storeSize).divide(new BigDecimal(GB), 2, RoundingMode.HALF_UP).doubleValue();
                break;
            case "TB":
                value = new BigDecimal(storeSize).divide(new BigDecimal(TB), 2, RoundingMode.HALF_UP).doubleValue();
                break;
            case "PB":
                value = new BigDecimal(storeSize).divide(new BigDecimal(PB), 2, RoundingMode.HALF_UP).doubleValue();
                break;
            default:
                value = Double.parseDouble(storeSize);
        }
        return value;
    }
}
